package baseclasses;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.content.Context;
import database.CourseDAO;

public class Course {
	
	//Problem domain variables
	private int id;
	private String name;
	private Calendar startTime;
	private Calendar endTime;
	private String location;
	
	//WeekdayBooleans array works with WeekDayStrings 
	//array for displaying to the user and mapping their selections
	private boolean[] weekDayBooleans;
	private final static String[] weekDayStrings = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
	
	//Default values for GPA calculation; 
	//also acts as flags for values that aren't set
	private double points = -1;
	private double outOf = -1;
	private double percentage = -1;
	
	
	private DecimalFormat df = new DecimalFormat("#.##"); //GPA decimal formatting
	private int credits = 3;	//default credit hours

	public Course(){	//base constructor is built upon by other constructors here
		weekDayBooleans = new boolean[]{false, false, false, false, false, false, false};
	}

	public Course( String name, Calendar startTime, boolean[] weekDayBooleans, Calendar endTime, String location )
	{	//Default constructor
		this.name = name;
		this.startTime = startTime;
		this.endTime = endTime;
		this.location = location;
		this.weekDayBooleans = weekDayBooleans;
		this.credits = 3;	//default credits set
	}

	public Course( int id, String name, Calendar startTime, boolean[] weekDayBooleans, Calendar endTime, String location )
	{	//Constructor used if course is created from EditAssignment class
		this.id = id;
		this.name = name;
		this.startTime = startTime;
		this.endTime = endTime;
		this.location = location;
		this.weekDayBooleans = weekDayBooleans;
		this.credits = 3;
	}


	public Course( String name, Calendar startTime, boolean[] weekDayBooleans, int credits, Calendar endTime, String location )
	{	//Used if course created from EditCourse
		this.name = name;
		this.startTime = startTime;
		this.endTime = endTime;
		this.location = location;
		this.weekDayBooleans = weekDayBooleans;
		this.credits = credits;
	}

	public Course( int id, String name, Calendar startTime, boolean[] weekDayBooleans, int credits, Calendar endTime, String location )
	{	//Used if created to retrofit grades for a course
		this.id = id;
		this.name = name;
		this.startTime = startTime;
		this.endTime = endTime;
		this.location = location;
		this.weekDayBooleans = weekDayBooleans;
		this.credits = credits;
	}
	
	public int getCredits() {
		return credits;
	}

	public void setCredits(int credits) {
		if(credits == 0){
			this.credits = 3;
		}
		else{
			this.credits = credits;
		}
	}

	public double getPoints(Context context) {
		if(this.points ==-1){	//If no grade points earned are set for the course
			this.points = CourseDAO.getGradePointsByCourse(context, this);
		}
		return points;
	}

	public void setPoints(double points) {
		this.points = points;
	}

	public double getOutOf(Context context) {
		if(this.outOf==-1){	//if total grade points set for course
			this.outOf  = CourseDAO.getGradePointsOutOfByCourse(context, this);
		}
		return outOf;
	}

	public void setOutOf(double outOf) {
		this.outOf = outOf;
	}

	public double getPercentage(Context context) {
		if(this.percentage==-1){	//if percentage not set, calculate and return
			percentage = getPoints(context)/getOutOf(context)*100;
		}
		return percentage;
	}

	public void setPercentage(double percentage) {
		this.percentage = percentage;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Calendar getStartTime() {
		return startTime;
	}

	public String getStartTimeString(String format){
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(startTime.getTimeInMillis());
	}

	public static String getStartTimeString(Calendar startTime, String format){
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(startTime.getTimeInMillis());
	}

	public void setStartTime(Calendar startTime) {
		this.startTime = startTime;
	}

	public void setStartTime(long time) {
		startTime = Calendar.getInstance();
		startTime.setTimeInMillis(time);
	}
	
	public String getEndTimeString( String format )
	{
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(endTime.getTimeInMillis());
	}
	
	public static String getEndTimeString( Calendar endTime, String format )
	{
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(endTime.getTimeInMillis());
	}
	
	public void setEndTime( Calendar endTime )
	{
		this.endTime = endTime;
	}
	
	public void setEndTime( long time )
	{
		endTime = Calendar.getInstance();
		endTime.setTimeInMillis(time);
	}
	
	public Calendar getEndTime()
	{
		return this.endTime;
	}
	
	public String getLocation()
	{
		return this.location;
	}
	
	public void setLocation( String location )
	{
		this.location = location;
	}
	

	public boolean[] getWeekDayBooleans() {
		return weekDayBooleans;
	}

	public void setWeekDayBooleans(boolean[] weekDayBooleans) {
		this.weekDayBooleans = weekDayBooleans;
	}

	public static String[] getWeekDayStrings() {
		return weekDayStrings;
	}

	//returns a readable string of the weekdays of the course
	public String getWeekDays(){

		boolean empty = true;
		String weekday = "";
		int count = 0;	//keeps track of how many days a week you have a course
						//for simpler string return

		for(int i=0;i<weekDayBooleans.length;i++){
			if(weekDayBooleans[i]==true){
				count++;
				if(empty){
					weekday = weekday + weekDayStrings[i].substring(0, 3); 
					//only want the first three letters of the weekday for display
					//on the first pass.
					empty = false;	//set empty to false to insert commas after subsequent entries
				}
				else{
					weekday = weekday + ", " +weekDayStrings[i].substring(0, 3);
				}
			}
		}
		if(count == 0){ 
			weekday = "none";
		}
		if(count == 7){
			weekday = "everyday";
		}
		return weekday;
	}

	//returns a readable string of the weekdays of the course
	public static String getWeekDays(boolean[] weekDayBooleans){

		boolean empty = true;
		String weekday = "";
		int count = 0;

		for(int i=0;i<weekDayBooleans.length;i++){
			if(weekDayBooleans[i]==true){
				count++;
				if(empty){	//will be the first time through
					weekday = weekday + weekDayStrings[i].substring(0, 3); //pop array with 1st 3 letters of weekdays present
					empty = false;	
				}
				else{
					weekday = weekday + ", " +weekDayStrings[i].substring(0, 3);
				}
			}
		}
		if(count == 0){
			weekday = "none";
		}
		if(count == 7){
			weekday = "everyday";
		}
		return weekday;
	}

	//returns a string containing the points earned, points out of, and percentage
  	//in a comprehensible format for the ViewGrades class		
	public String getGradeString(Context context){
		return getPoints(context)+" / "+getOutOf(context)+"     "+df.format(getPercentage(context))+"%";
	}

	@Override
	public String toString(){
		return name;
	}

	public double getWeight(Context context){
		//Calculates grade points for a course based on credit hour
		//Scale found via google

		double per = getPercentage(context);

		if(per >= 93.0){
			return 4.0;
		}
		else if(per >= 90.0){
			return 3.67;
		}
		else if(per >= 87.0){
			return 3.33;
		}
		else if(per >= 83.0){
			return 3.0;
		}
		else if(per >= 80.0){
			return 2.67;
		}
		else if(per >= 77.0){
			return 2.33;
		}
		else if(per >= 73.0){
			return 2.0;
		}
		else if(per >= 70.0){
			return 1.67;
		}
		else if(per >= 67.0){
			return 1.33;
		}
		else if(per >= 63.0){
			return 1.0;
		}
		else if(per >= 60.0){
			return  0.67;
		}
		else if(per < 60.0){
			return 0;
		}
		else{
			return -1;
		}

	}

}
